#include <cppunit/config/SourcePrefix.h>
#include "TestVarTable.h"
#include <string>
#include <algorithm>
using namespace std;

void TestVarTable::setUp() {
	table = VarTable();
}

void TestVarTable::tearDown() {
}

CPPUNIT_TEST_SUITE_REGISTRATION( TestVarTable );

void TestVarTable::testAddVar(){
	int index;

	index = table.addVar(string("x"),1);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("variable \"x\" added to index 0", 0, index);
	CPPUNIT_ASSERT_MESSAGE("entry of \"x\" has size 1 and contains stmtNumber 1", 
							table.getStmts(index).size() == 1
							&& find(table.getStmts(index).begin(),table.getStmts(index).end(),1) != table.getStmts(index).end());

	index = table.addVar(string("y"),2);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("variable \"y\" added to index 1", 1, index);
	CPPUNIT_ASSERT_MESSAGE("entry of \"y\" has size 1 and contains stmtNumber 1", 
							table.getStmts(index).size() == 1
							&& find(table.getStmts(index).begin(),table.getStmts(index).end(),2) != table.getStmts(index).end());
	
	index = table.addVar(string("z"),3);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("variable \"z\" added to index 2", 2, index);
	CPPUNIT_ASSERT_MESSAGE("entry of \"z\" has size 1 and contains stmtNumber 1", 
							table.getStmts(index).size() == 1
							&& find(table.getStmts(index).begin(),table.getStmts(index).end(),3) != table.getStmts(index).end());
	
	index = table.addVar(string("x"),4);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("reinsert \"x\"", 0, index);
	CPPUNIT_ASSERT_MESSAGE("entry of \"x\" has size 2 and contains stmtNumber 1 and 4", 
							table.getStmts(index).size() == 2
							&& find(table.getStmts(index).begin(),table.getStmts(index).end(),1) != table.getStmts(index).end()
							&& find(table.getStmts(index).begin(),table.getStmts(index).end(),4) != table.getStmts(index).end());
}

void TestVarTable::testAddVarNodeID(){
	int indexX = table.addVar(string("x"),1);
	
	CPPUNIT_ASSERT_EQUAL_MESSAGE("add nodeID 1 to variable \"x\"", true, table.addVarNodeID(indexX,1));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("re-add nodeID 1 to variable \"x\"", false, table.addVarNodeID(indexX,1));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("add nodeID 2 to non-existent variable", false, table.addVarNodeID(1000000,1));		
}

void TestVarTable::testGetIndex(){
	int indexX = table.addVar(string("x"),1);
	int indexY = table.addVar(string("y"),2);
	int indexZ = table.addVar(string("z"),3);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for index of \"x\"", indexX, table.getIndex(string("x")));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for index of \"y\"", indexY, table.getIndex(string("y")));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for index of \"z\"", indexZ, table.getIndex(string("z")));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for unknown variable", -1, table.getIndex(string("unknown")));
}

void TestVarTable::testGetVarName(){
	int indexX = table.addVar(string("x"),1);
	int indexY = table.addVar(string("y"),2);
	int indexZ = table.addVar(string("z"),3);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for \"x\"", string("x"), table.getVarName(indexX));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for \"y\"", string("y"), table.getVarName(indexY));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for \"z\"", string("z"), table.getVarName(indexZ));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for unknown variable", string(""), table.getVarName(1000000));
}

void TestVarTable::testGetStmts(){
	int indexX = 0;
	CPPUNIT_ASSERT_MESSAGE("get stmts of unknown variable", table.getStmts(indexX).empty());
	indexX = table.addVar(string("x"),1);
	CPPUNIT_ASSERT_MESSAGE("get stmts of \"x\"", 
							table.getStmts(indexX).size() == 1 
							&& find(table.getStmts(indexX).begin(),table.getStmts(indexX).end(),1) != table.getStmts(indexX).end());
	indexX = table.addVar(string("x"),2);
	CPPUNIT_ASSERT_MESSAGE("get stmts of \"x\"", 
							table.getStmts(indexX).size() == 2 
							&& find(table.getStmts(indexX).begin(),table.getStmts(indexX).end(),1) != table.getStmts(indexX).end()
							&& find(table.getStmts(indexX).begin(),table.getStmts(indexX).end(),2) != table.getStmts(indexX).end());
}

void TestVarTable::testGetNodeIDs(){
	int indexX = 0;
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of unknown variable", table.getNodeIDs(indexX).empty());
	indexX = table.addVar(string("x"),1);
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of \"x\"", 
							table.getNodeIDs(indexX).size() == 0);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("successfully add node id 1 to \"x\"", true, table.addVarNodeID(indexX,1));
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of \"x\"",
							table.getNodeIDs(indexX).size() == 1
							&& find(table.getNodeIDs(indexX).begin(),table.getNodeIDs(indexX).end(),1) != table.getNodeIDs(indexX).end());
	CPPUNIT_ASSERT_EQUAL_MESSAGE("successfully add node id 2 to \"x\"", true, table.addVarNodeID(indexX,2));
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of \"x\"", 
							table.getNodeIDs(indexX).size() == 2
							&& find(table.getNodeIDs(indexX).begin(),table.getNodeIDs(indexX).end(),1) != table.getNodeIDs(indexX).end()
							&& find(table.getNodeIDs(indexX).begin(),table.getNodeIDs(indexX).end(),2) != table.getNodeIDs(indexX).end());
	CPPUNIT_ASSERT_EQUAL_MESSAGE("fail to re-add node id 1 to \"x\"", false, table.addVarNodeID(indexX,1));
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of \"x\"", 
							table.getNodeIDs(indexX).size() == 2
							&& find(table.getNodeIDs(indexX).begin(),table.getNodeIDs(indexX).end(),1) != table.getNodeIDs(indexX).end()
							&& find(table.getNodeIDs(indexX).begin(),table.getNodeIDs(indexX).end(),2) != table.getNodeIDs(indexX).end());
}
